home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / util / pack / xfdmaster.lha / xfd / Developer / Sources / ASM / TUC.a < prev    next >
Text File  |  1999-02-05  |  20KB  |  958 lines

  1. ********************************************************
  2. **        XFD external decruncher for TUC 1.16        **
  3. **               © 1998 by Georg Hörmann              **
  4. ********************************************************
  5. **
  6. ** 1.0    - Initial release.
  7. ** 1.1    - Added support for data files.
  8. **    - Added support for address files.
  9. **
  10.  
  11.         OUTPUT    "LIBS:xfd/TUC"
  12.  
  13.         SECTION    TUC,CODE
  14.  
  15.         INCDIR    "dh0:Include_Asm"
  16.         INCLUDE    "dh0:xfd/xfdmaster.i"
  17.  
  18. F_TUC        moveq    #-1,d0
  19.         rts
  20.         dc.l    XFDF_ID
  21.         dc.w    1
  22.         dc.w    0
  23.         dc.l    0,0
  24.         dc.l    S_TUC
  25.  
  26.         dc.b    "$VER: xfd_TUC_1.16 1.1 (13.12.98) © 1998 Georg Hörmann",0
  27.         cnop    0,4
  28.  
  29. ********************************************************
  30. *
  31. * Reloc files will always be restored to their original
  32. * appearance.
  33. *
  34. * Address files will be treated as follows:
  35. * a. If more than 1 hunk, a reloc file will be created.
  36. *    The first hunk gets the MEM_TYPE of the decrunch
  37. *    address.
  38. * b. If 1 hunk with reloc information, same as a.
  39. * c. If 1 hunk without reloc information, it could be
  40. *    a relocated image and therefore gets a small
  41. *    header in front that copies it to the decrunch
  42. *    address. Only such files support the "Rückwärts"
  43. *    option.
  44. *
  45.  
  46. S_TUC        dc.l    S_TUCData
  47.         dc.w    2
  48.         dc.w    36
  49.         dc.l    N_TUC
  50.         dc.w    XFDPFF_RELOC
  51.         dc.w    0
  52.         dc.l    RB_TUC
  53.         dc.l    DB_TUC
  54.         dc.l    0
  55.         dc.l    0
  56.         dc.w    0
  57.         dc.w    0
  58.         dc.l    $1c8+4+12
  59.  
  60. N_TUC        dc.b    'TUC 1.16',0
  61.         even
  62.  
  63. ;-------------------------------------------------
  64.  
  65. RB_TUC        cmp.l    #$3f3,(a0)
  66.         bne.s    .Exit
  67.         move.l    8(a0),d1
  68.         lsl.w    #2,d1
  69.         lea    20+4(a0,d1.w),a0
  70.         cmp.l    #$55,(a0)+        ;header length
  71.         bne.s    .Exit
  72.         cmp.l    #$7e001e1d,$36-$2c(a0)
  73.         bne.s    .Exit
  74.         cmp.l    #$48471e1d,$3a-$2c(a0)
  75.         bne.s    .Exit
  76.         cmp.l    #$49f50000,$4c-$2c(a0)
  77.         bne.s    .Exit
  78.         cmp.l    #$bd834846,$5a-$2c(a0)
  79.         bne.s    .Exit
  80.         moveq    #1,d0
  81.         rts
  82. .Exit        moveq    #0,d0
  83.         rts
  84.  
  85. ;-------------------------------------------------
  86.  
  87. TUC_BSS        SET    xfdBufferInfo_SIZE
  88. TUC_CrunchedData SET    xfdBufferInfo_SIZE+4
  89. TUC_CountSize    SET    xfdBufferInfo_SIZE+8
  90. TUC_CountStruct    SET    xfdBufferInfo_SIZE+12
  91. TUC_EorValue    SET    xfdBufferInfo_SIZE+16
  92. TUC_Mode    SET    xfdBufferInfo_SIZE+20    ;1=reloc, 0=addr, -1=image
  93. TUC_Back    SET    xfdBufferInfo_SIZE+21
  94. TUC_JmpAddr    SET    xfdBufferInfo_SIZE+22
  95. TUC_DecAddr    SET    xfdBufferInfo_SIZE+26
  96. TUC_SIZE    SET    xfdBufferInfo_SIZE+30
  97.  
  98. DB_TUC        movem.l    d2-d7/a2-a6,-(a7)
  99.         sub.w    #TUC_SIZE,a7
  100.         move.l    a7,a5
  101.         move.l    a0,-(a7)    ;bufferinfo
  102.         move.l    a5,a1
  103.         moveq    #xfdBufferInfo_SIZE-1,d1
  104. .CopyBI1    move.b    (a0)+,(a1)+
  105.         dbf    d1,.CopyBI1
  106.  
  107. * get some addresses and sizes
  108.  
  109.         move.l    xfdbi_SourceBuffer(a5),a0
  110.         move.l    8(a0),d1
  111.  
  112.         move.l    d1,d0
  113.         lsl.l    #2,d0
  114.         lea    20(a0,d0.w),a0        ;start of code hunk
  115.  
  116.         move.l    $40-$24(a0),d0
  117.         eor.l    #"rich",d0
  118.         move.l    d0,TUC_EorValue(a5)
  119.         move.l    $160-$24(a0),TUC_JmpAddr(a5)
  120.  
  121.         sf    TUC_Mode(a5)
  122.         cmp.w    #$2094,$158-$24(a0)    ;only used by reloc mode
  123.         bne.s    .Mode_Ok
  124.         move.b    #1,TUC_Mode(a5)        ;reloc
  125.  
  126. .Mode_Ok    sf    TUC_Back(a5)
  127.         cmp.w    #$4480,$110-$24(a0)    ;forward mode
  128.         beq.s    .Back_Ok
  129.         st    TUC_Back(a5)
  130.  
  131. .Back_Ok    move.l    4(a0),d0
  132.         lsl.l    #2,d0
  133.         lea    8+24(a0,d0.l),a0    ;end of code+reloc hunk
  134.         move.l    a0,TUC_BSS(a5)
  135.  
  136.         move.l    d1,d0
  137.         subq.w    #2,d0        ;amount of bss hunks
  138.         mulu    #12,d0
  139.         lea    8(a0,d0.l),a0        ;start of crunched data
  140.         move.l    a0,TUC_CrunchedData(a5)
  141.  
  142.         moveq    #0,d0
  143.         move.b    1(a0),d0        ;amount hunks
  144.         move.l    d0,d7        ;amount of hunks
  145.  
  146.         moveq    #1,d2
  147.         add.w    d0,d2
  148.         lsl.l    #2,d2
  149.         move.l    d2,TUC_CountSize(a5)
  150.         mulu    d0,d2        ;length of CountStructs
  151.  
  152.         addq.l    #4,d2        ;for length
  153.         move.l    d2,d0
  154.         move.l    #$10001,d1
  155.         move.l    4.w,a6
  156.         jsr    -198(a6)
  157.         move.w    #XFDERR_NOMEMORY,xfdbi_Error(a5)
  158.         tst.l    d0
  159.         beq    .Exit
  160.         move.l    d0,a0
  161.         move.l    d2,(a0)+
  162.         move.l    a0,TUC_CountStruct(a5)
  163.  
  164.         move.l    d7,-(a7)
  165.         bsr    TUC_Count
  166.         move.l    (a7)+,d7
  167.         move.w    #XFDERR_CORRUPTEDDATA,xfdbi_Error(a5)
  168.         tst.w    d0
  169.         beq    .ExitFree
  170.  
  171. * calculate length of final file
  172.  
  173.         move.l    TUC_CountStruct(a5),a3
  174.         moveq    #20,d0        ;3f3,0,x,0,x-1
  175.         move.l    d7,d1
  176.         lsl.l    #4,d1
  177.         add.l    d1,d0        ;header,3e9/a/b,len,3f2
  178.  
  179.         move.w    d7,d3
  180. .CalcNext    move.l    (a3),d1        ;is BSS ??
  181.         beq.s    .SkipReloc
  182.         add.l    d1,d0        ;hunklen
  183.  
  184.         move.w    d7,d2
  185.         moveq    #0,d4
  186.         moveq    #0,d5        ;3ec flag
  187. .TestNextReloc    move.l    4(a3,d4.w),d1
  188.         beq.s    .NoReloc
  189.         tst.w    d5
  190.         bne.s    .Skip3ec
  191.         addq.l    #8,d0        ;3ec, 0 am ende
  192.         moveq    #1,d5
  193. .Skip3ec    addq.l    #8,d0        ;x,hunk #
  194.         lsl.l    #2,d1
  195.         add.l    d1,d0        ;offsets
  196. .NoReloc    addq.w    #4,d4
  197.         subq.w    #1,d2
  198.         bne.s    .TestNextReloc
  199.  
  200. .SkipReloc    add.l    TUC_CountSize(a5),a3
  201.         subq.w    #1,d3
  202.         bne.s    .CalcNext
  203.  
  204.         tst.b    TUC_Mode(a5)    ;reloc, mode=1
  205.         beq.s    .Test_Addr
  206.         move.l    TUC_DecAddr(a5),d1    ;really reloc or just no JmpAddr?
  207.         beq.s    .Mode_Ok2
  208.         move.l    d1,TUC_JmpAddr(a5)
  209.         sf    TUC_Mode(a5)
  210. .Test_Addr    cmp.w    #1,d7        ;more than 1 hunk, mode=0
  211.         bne.s    .Mode_Ok2
  212.         move.l    TUC_CountStruct(a5),a0
  213.         tst.l    4(a0)        ;one hunk, but with relocs, mode=0
  214.         bne.s    .Mode_Ok2
  215.         st    TUC_Mode(a5)    ;image, mode=-1
  216.         add.l    #TUCAddr_End-TUCAddr_Start,d0
  217.  
  218. .Mode_Ok2    move.l    d0,xfdbi_TargetBufSaveLen(a5)
  219.         move.l    d0,xfdbi_TargetBufLen(a5)
  220.         move.l    xfdbi_TargetBufMemType(a5),d1
  221.         move.l    4.w,a6
  222.         jsr    -198(a6)
  223.         move.w    #XFDERR_NOMEMORY,xfdbi_Error(a5)
  224.         move.l    d0,xfdbi_TargetBuffer(a5)
  225.         beq    .ExitFree
  226.  
  227. * prepare allocated buffer
  228.  
  229.         move.l    d0,a1
  230.         move.l    #$3f3,(a1)+
  231.         clr.l    (a1)+
  232.         move.l    d7,(a1)+
  233.         clr.l    (a1)+
  234.         move.l    d7,d0
  235.         subq.l    #1,d0
  236.         move.l    d0,(a1)+
  237.  
  238.         move.l    TUC_CountStruct(a5),a3
  239.  
  240.         move.l    xfdbi_SourceBuffer(a5),a0
  241.         add.w    #20+4,a0
  242.         move.w    d7,d0
  243.         cmp.b    #1,TUC_Mode(a5)        ;if reloc, just copy header
  244.         beq.s    .CopyHunkHeader
  245.         move.l    (a3),d1            ;else, use coded hunklen
  246.         tst.b    TUC_Mode(a5)
  247.         beq.s    .NoImage
  248.         add.l    #TUCAddr_End-TUCAddr_Start,d1
  249. .NoImage    lsr.l    #2,d1
  250.         tst.b    TUC_Mode(a5)        ;get MEM_TYPE
  251.         bmi.s    .NoMemType
  252.         movem.l    d0/d1/a0/a1,-(a7)
  253.         move.l    TUC_DecAddr(a5),a1
  254.         jsr    -534(a6)    ;typeofmem
  255.         move.l    d0,d2
  256.         movem.l    (a7)+,d0/d1/a0/a1
  257.         beq.s    .NoMemType
  258.         and.w    #$0002,d2
  259.         beq.s    .NoMemType
  260.         or.l    #$40000000,d1
  261. .NoMemType    move.l    d1,(a1)+
  262.         bra.s    .SkipHunkHeader
  263. .CopyHunkHeader    move.l    (a0)+,(a1)+
  264. .SkipHunkHeader    subq.w    #1,d0
  265.         bne.s    .CopyHunkHeader
  266.  
  267.         move.l    TUC_BSS(a5),a2
  268.         addq.w    #4,a2
  269.         moveq    #0,d6        ;flag for bss
  270.  
  271.         move.w    d7,d0
  272. .PrepareHunks    tst.l    (a3)
  273.         beq    .BSS
  274.         move.l    #$3e9,(a1)+
  275.  
  276.         cmp.b    #1,TUC_Mode(a5)
  277.         beq.s    .UseBSS
  278.         tst.w    d6
  279.         bne.s    .UseBSS
  280.         move.l    (a3),d1
  281.         tst.b    TUC_Mode(a5)
  282.         beq.s    .NoImage2
  283.         add.l    #TUCAddr_End-TUCAddr_Start,d1
  284. .NoImage2    lsr.l    #2,d1
  285.         subq.w    #8,a2        ;correct add at end
  286.         moveq    #1,d6
  287.         bra.s    .SkipBSS
  288. .UseBSS        move.l    (a2)+,d1
  289. .SkipBSS    move.l    d1,(a1)+
  290.  
  291.         tst.b    TUC_Mode(a5)    ;copy address header
  292.         bge.s    .NoImage3
  293.         moveq    #(TUCAddr_End-TUCAddr_Start)/4,d2
  294.         sub.l    d2,d1
  295.         lea    TUCAddr_Start(pc),a0
  296. .CopyAddr    move.l    (a0)+,(a1)+
  297.         subq.l    #1,d2
  298.         bne.s    .CopyAddr
  299.         move.l    TUC_DecAddr(a5),TUCAddr_DecAddr+2-TUCAddr_End(a1)
  300.         move.l    TUC_JmpAddr(a5),TUCAddr_JmpAddr+2-TUCAddr_End(a1)
  301.         move.l    (a3),TUCAddr_DataLen+2-TUCAddr_End(a1)
  302.  
  303. .NoImage3    move.l    a1,(a3)        ;save pointer to hunk
  304.         lsl.l    #2,d1
  305.         add.l    d1,a1        ;skip code/data
  306.  
  307.         move.w    d7,d1
  308.         moveq    #0,d2
  309.         moveq    #0,d3        ;flag
  310. .PrepareReloc    move.l    4(a3,d2.w),d4
  311.         beq.s    .NoReloc_1
  312.         tst.w    d3
  313.         bne.s    .Skip3ec_1
  314.         move.l    #$3ec,(a1)+
  315.         moveq    #1,d3
  316. .Skip3ec_1    move.l    d4,(a1)+    ;x hunks
  317.         lsr.w    #2,d2
  318.         move.l    d2,(a1)+    ;hunk #
  319.         lsl.w    #2,d2
  320.         move.l    a1,4(a3,d2.w)    ;save pointer for decrunching
  321.         lsl.l    #2,d4
  322.         add.l    d4,a1        ;skip offsets
  323. .NoReloc_1    addq.w    #4,d2
  324.         subq.w    #1,d1
  325.         bne.s    .PrepareReloc
  326.         tst.w    d3
  327.         beq.s    .NextHunk
  328.         clr.l    (a1)+
  329.         bra.s    .NextHunk
  330.  
  331. .BSS        move.l    #$3eb,(a1)+
  332.         move.l    (a2)+,(a1)+
  333.         clr.l    (a3)        ;no pointer needed
  334. .NextHunk    move.l    #$3f2,(a1)+
  335.         addq.w    #8,a2
  336.         add.l    TUC_CountSize(a5),a3
  337.         subq.w    #1,d0
  338.         bne    .PrepareHunks
  339.  
  340.         bsr    TUC_Decrunch
  341.  
  342.         tst.b    TUC_Mode(a5)
  343.         bge.s    .Ok
  344.         tst.b    TUC_Back(a5)
  345.         beq.s    .Ok
  346.  
  347.         move.l    xfdbi_TargetBuffer(a5),a0
  348.         add.w    #20+4+8+(TUCAddr_End-TUCAddr_Start),a0
  349.         move.l    TUCAddr_DataLen+2-TUCAddr_End(a0),d0
  350.         lea    (a0,d0.l),a1
  351.         lsr.l    #1,d0
  352. .Switch        move.b    (a0),d1
  353.         move.b    -(a1),(a0)+
  354.         move.b    d1,(a1)
  355.         subq.l    #1,d0
  356.         bne.s    .Switch
  357.  
  358. .Ok        moveq    #1,d0
  359.  
  360. .ExitFree    move.l    d0,-(a7)
  361.         move.l    TUC_CountStruct(a5),a1
  362.         move.l    -(a1),d0
  363.         move.l    4.w,a6
  364.         jsr    -210(a6)
  365.         move.l    (a7)+,d0
  366.  
  367. .Exit        move.l    (a7)+,a1    ;bufferinfo
  368.         moveq    #xfdBufferInfo_SIZE-1,d1
  369. .CopyBI2    move.b    (a5)+,(a1)+
  370.         dbf    d1,.CopyBI2
  371.         add.w    #TUC_SIZE,a7
  372.         movem.l    (a7)+,d2-d7/a2-a6
  373.         rts
  374.  
  375.         cnop    0,4
  376.  
  377. TUCAddr_Start    movem.l    d0/d1/a0/a1/a6,-(a7)
  378. TUCAddr_DecAddr    lea    $12345678,a1
  379. TUCAddr_DataLen    move.l    #$12345678,d0
  380.         move.l    4.w,a6
  381.         jsr    -204(a6)
  382.         tst.l    d0
  383.         bne.s    .Ok
  384.         add.w    #20,a7
  385.         rts
  386. .Ok        lea    TUCAddr_End(pc),a0
  387.         move.l    TUCAddr_DecAddr+2(pc),a1
  388.         move.l    TUCAddr_DataLen+2(pc),d0
  389.         jsr    -624(a6)
  390.         movem.l    (a7)+,d0/d1/a0/a1/a6
  391. TUCAddr_JmpAddr    jmp    $12345678
  392.  
  393.         cnop    0,4
  394. TUCAddr_End
  395.  
  396. ;-------------------------------------------------
  397.  
  398. *
  399. *    CountStruct:
  400. *
  401. *    ULONG    HunkLen              ]
  402. *    ULONG    Relocs to Hunk 0     ] (n+1)*4
  403. *    ...                          ]
  404. *    ULONG    Relocs to Hunk n-1   ]
  405. *
  406. * This structure is needed for every crunched hunk !
  407. *
  408.  
  409. TUC_Count    move.l    TUC_CrunchedData(a5),a0
  410.         moveq    #0,d7
  411.         move.b    (a0)+,d7        ;bits needed for highest hunk #
  412.         swap    d7
  413.         move.b    (a0)+,d7        ;amount hunks
  414.                         ;a0: table of hunk len bits
  415.         move.w    d7,d0
  416.         addq.w    #1,d0
  417.         and.w    #$fe,d0
  418.         lea    (a0,d0.w),a2        ;hunk table
  419.         move.l    (a2),TUC_DecAddr(a5)
  420.         move.w    d7,d0
  421.         asl.w    #2,d0
  422.         lea    20(a2,d0.w),a2        ;data begin first hunk
  423.         move.l    TUC_EorValue(a5),d3
  424.         move.l    TUC_CountStruct(a5),a3
  425.         moveq    #0,d6            ;hunk count
  426.  
  427. .lbC00003A    moveq    #0,d5
  428.         move.w    (a2)+,d0        ;info table length
  429.         beq    .lbC0000FE
  430.         move.l    a2,a6            ;info table
  431.         lea    (a2,d0.w),a2
  432.         move.w    d6,d0
  433.         moveq    #0,d1
  434.         move.b    (a0,d0.w),d1        ;bit width of hunk length
  435.         bsr    TUC_GetBits
  436.         move.l    d0,d4            ;hunk length
  437.         move.l    d0,(a3)
  438.  
  439. .lbC000062    moveq    #0,d0
  440. .lbC000064    asl.l    #1,d5            ;get value from info table
  441.         bne.s    .lbC000072
  442.         move.l    (a2)+,d5
  443.         eor.l    d3,d5
  444.         move.b    #$10,ccr
  445.         roxl.l    #1,d5
  446. .lbC000072    bcc.s    .lbC000076
  447.         addq.w    #2,d0
  448. .lbC000076    move.w    (a6,d0.w),d0        ;loop until negative
  449.         bpl.s    .lbC000064
  450.         not.w    d0
  451.  
  452.         cmp.w    #$100,d0        ;less than $100 -> data byte
  453.         bcs.s    .lbC0000F0
  454.         bne.s    .lbC0000A6        ;more than $100 -> crunched
  455.  
  456. * reloc info
  457.  
  458.         move.l    d7,d1
  459.         swap    d1            ;bits needed for hunk #
  460.         bsr.s    TUC_GetBits        ;d0: hunk number
  461.         move.w    d0,d1
  462.         lsl.w    #2,d1
  463.         addq.l    #1,4(a3,d1.w)        ;count reloc to hunk x
  464.         moveq    #0,d1
  465.         move.b    (a0,d0.w),d1        ;bits of hunk length
  466.         bsr.s    TUC_GetBits
  467.         subq.l    #4,d4
  468.         bra.s    .lbC0000F2
  469.  
  470. * crunched
  471.  
  472. .lbC0000A6    cmp.w    #$110,d0        ;$101-$110
  473.         bhi.s    .lbC0000C6
  474.         sub.w    #$101,d0
  475.         move.w    d0,d1            ;value 0-$f
  476.         bsr.s    TUC_GetBits
  477.         sub.l    d0,d4
  478.         moveq    #7,d1
  479.         bsr.s    TUC_GetBits
  480.         subq.l    #2,d4
  481.         bra.s    .lbC0000F2
  482.  
  483. .lbC0000C6    move.w    d0,d2            ;$111-$1ff
  484.         move.w    d0,d1
  485.         and.w    #15,d1
  486.         bsr.s    TUC_GetBits
  487.         addq.w    #3,d0            ;length of string
  488.         sub.l    d0,d4
  489.  
  490.         move.w    d2,d1
  491.         lsr.w    #4,d1
  492.         and.w    #15,d1
  493.         addq.w    #2,d1
  494.         bsr.s    TUC_GetBits
  495.  
  496. * copy uncrunched byte
  497.  
  498. .lbC0000F0    subq.l    #1,d4
  499. .lbC0000F2    bmi.s    .Error
  500.         bne.s    .lbC000062
  501.  
  502. .lbC0000FE    add.l    TUC_CountSize(a5),a3
  503.         addq.w    #1,d6
  504.         cmp.w    d7,d6            ;last hunk ??
  505.         bcs    .lbC00003A
  506.         moveq    #1,d0
  507.         rts
  508.  
  509. .Error        moveq    #0,d0
  510.         rts
  511.  
  512. TUC_GetBits    moveq    #0,d0
  513. .lbC00013A    asl.l    #1,d5
  514.         bne.s    .lbC000148
  515.         move.l    (a2)+,d5
  516.         eor.l    d3,d5
  517.         move.b    #$10,ccr
  518.         roxl.l    #1,d5
  519. .lbC000148    roxl.l    #1,d0
  520.         dbra    d1,.lbC00013A
  521.         rts
  522.  
  523. ;-------------------------------------------------
  524.  
  525. TUC_Decrunch    move.l    TUC_CrunchedData(a5),a0
  526.         move.l    TUC_CountStruct(a5),a3
  527.  
  528.         moveq    #0,d7
  529.         move.b    (a0)+,d7        ;bits needed for highest hunk #
  530.         swap    d7
  531.         move.b    (a0)+,d7        ;amount hunks
  532.  
  533. * a0: table of hunk lengths (bits to calculate hunk length)
  534.  
  535.         move.w    d7,d0
  536.         addq.w    #1,d0
  537.         and.w    #$fe,d0
  538.         lea    (a0,d0.w),a2        ;hunk table
  539.         move.w    d7,d0
  540.         asl.w    #2,d0
  541.         lea    20(a2,d0.w),a2        ;data begin first hunk
  542.         move.l    TUC_EorValue(a5),d3
  543.  
  544.         moveq    #0,d6            ;hunk count
  545.  
  546. .lbC00003A    moveq    #0,d5
  547.         move.l    (a3),a1            ;pointer to hunk
  548.         move.w    (a2)+,d0        ;info table length
  549.         beq    .lbC0000FE
  550.         move.l    a2,a6            ;info table
  551.         lea    (a2,d0.w),a2
  552.         move.w    d6,d0
  553.         moveq    #0,d1
  554.         move.b    (a0,d0.w),d1        ;bit width of hunk length
  555.         bsr.s    TUC_GetBits
  556.         move.l    d0,d4            ;hunk length
  557.         add.l    a1,d4            ;end of hunk
  558.  
  559. .lbC000062    moveq    #0,d0
  560. .lbC000064    asl.l    #1,d5            ;get value from info table
  561.         bne.s    .lbC000072
  562.         move.l    (a2)+,d5
  563.         eor.l    d3,d5
  564.         move.b    #$10,ccr
  565.         roxl.l    #1,d5
  566. .lbC000072    bcc.s    .lbC000076
  567.         addq.w    #2,d0
  568. .lbC000076    move.w    (a6,d0.w),d0        ;loop until negative
  569.         bpl.s    .lbC000064
  570.         not.w    d0
  571.  
  572.         cmp.w    #$100,d0        ;less than $100 -> data byte
  573.         bcs.s    .lbC0000F0
  574.         bne.s    .lbC0000A6        ;more than $100 -> crunched
  575.  
  576. * reloc info
  577.  
  578.         move.l    d7,d1
  579.         swap    d1            ;bits needed for hunk #
  580.         bsr    TUC_GetBits
  581.         moveq    #0,d1
  582.         move.b    (a0,d0.w),d1        ;bits of hunk length
  583.         move.w    d0,d2            ;d2: hunk number
  584.         bsr    TUC_GetBits
  585.         move.l    d5,-(a7)
  586.         lsl.w    #2,d2
  587.         move.l    4(a3,d2.w),a4        ;current reloc pointer
  588.         move.l    (a3),d5
  589.         neg.l    d5
  590.         add.l    a1,d5            ;offset
  591.         move.l    d5,(a4)+
  592.         move.l    a4,4(a3,d2.w)        ;save back pointer
  593.         move.l    d0,(a1)+        ;save longword
  594.         move.l    (a7)+,d5
  595.         bra.s    .lbC0000F2
  596.  
  597. * crunched
  598.  
  599. .lbC0000A6    cmp.w    #$110,d0        ;$101-$110
  600.         bhi.s    .lbC0000C6
  601.         sub.w    #$101,d0
  602.         move.w    d0,d1            ;value 0-$f
  603.         bsr    TUC_GetBits
  604.         move.w    d0,d2            ;amount of same bytes
  605.         moveq    #7,d1
  606.         bsr    TUC_GetBits
  607. .lbC0000BE    move.b    d0,(a1)+        ;copy same bytes
  608.         dbra    d2,.lbC0000BE
  609.         bra.s    .lbC0000F0
  610.  
  611. .lbC0000C6    move.w    d0,d2            ;$111-$1ff
  612.         move.w    d0,d1
  613.         and.w    #15,d1
  614.         bsr    TUC_GetBits
  615.         addq.w    #3,d0            ;length of string
  616.         move.w    d2,d1
  617.         move.w    d0,d2
  618.         lsr.w    #4,d1
  619.         and.w    #15,d1
  620.         addq.w    #2,d1
  621.         bsr    TUC_GetBits
  622.         neg.l    d0            ;offset
  623. .lbC0000E6    move.b    (a1,d0.l),(a1)+
  624.         dbra    d2,.lbC0000E6
  625.         bra.s    .lbC0000F2
  626.  
  627. * copy uncrunched byte
  628.  
  629. .lbC0000F0    move.b    d0,(a1)+
  630. .lbC0000F2    cmp.l    d4,a1            ;end of hunk ??
  631.         bne    .lbC000062
  632. .lbC0000FE    add.l    TUC_CountSize(a5),a3
  633.         addq.w    #1,d6
  634.         cmp.w    d7,d6            ;last hunk ??
  635.         bcs    .lbC00003A
  636.         rts
  637.  
  638. **********************************************************
  639. *
  640. * Data files must have the following format:
  641. *
  642. * - Only one "hunk" (starting with $0001)
  643. * - Address of the "hunk" must be "TUC!" (that's the ID)
  644. * - No reloc information (bitcode $100)
  645. *
  646. * The "Rückwärts" option cannot be recognized in any way,
  647. * you have to switch bytes by hand if such a file appears.
  648. *
  649.  
  650. S_TUCData    dc.l    0
  651.         dc.w    2
  652.         dc.w    38
  653.         dc.l    N_TUCData
  654.         dc.w    XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
  655.         dc.w    0
  656.         dc.l    RB_TUCData
  657.         dc.l    DB_TUCData
  658.         dc.l    SD_TUCData
  659.         dc.l    VD_TUCData
  660.         dc.w    0
  661.         dc.w    0
  662.         dc.l    $1c+2+2+4
  663.  
  664. N_TUCData    dc.b    'TUC 1.16 Data',0
  665.         even
  666.  
  667. ;-------------------------------------------------
  668.  
  669. RB_TUCData    bsr.s    RB_TUCDataID
  670.         beq.s    .Out
  671.         cmp.w    #$0001,(a0)        ;only data with 1 "hunk"
  672.         bne.s    .Exit
  673.         move.w    $1c(a0),d0        ;info table length
  674.         beq.s    .Out
  675.         movem.l    d3/d5/a2,-(a7)
  676.         lea    $1e(a0,d0.w),a2
  677.         moveq    #0,d1
  678.         move.b    2(a0),d1        ;bit width of hunk length
  679.         moveq    #0,d5
  680.         move.l    8(a0),d3        ;calculate EOR value
  681.         eor.l    #"M.F.",d3
  682.         neg.l    d3
  683.         swap    d3
  684.         ror.l    #8,d3
  685.         bsr    TUC_GetBits
  686.         movem.l    (a7)+,d3/d5/a2
  687.         move.l    d0,xfdrr_MinTargetLen(a1)
  688.         move.l    d0,xfdrr_FinalTargetLen(a1)
  689.         moveq    #1,d0
  690.         rts
  691. .Exit        moveq    #0,d0
  692. .Out        rts
  693.  
  694.  
  695. RB_TUCDataID    cmp.l    #"TUC!",4(a0)
  696.         bne.s    .Exit
  697.         cmp.l    #"TUC ",$c(a0)
  698.         bne.s    .Exit
  699.         cmp.l    #" M.F",$10(a0)
  700.         bne.s    .Exit
  701.         cmp.l    #"ried",$14(a0)
  702.         bne.s    .Exit
  703.         cmp.l    #"rich",$18(a0)
  704.         bne.s    .Exit
  705.         moveq    #1,d0
  706.         rts
  707. .Exit        moveq    #0,d0
  708.         rts
  709.  
  710. ;-------------------------------------------------
  711.  
  712. SD_TUCData    cmp.w    #$0001,(a0)        ;only data with 1 "hunk"
  713.         bne.s    .Exit
  714.         cmp.l    #$1e,d0            ;length to scan
  715.         blt.s    .Exit
  716.         bsr.s    RB_TUCDataID
  717.         beq.s    .Out
  718.         tst.w    $1c(a0)            ;info table length
  719.         beq.s    .Exit
  720.         rts
  721. .Exit        moveq    #0,d0
  722. .Out        rts
  723.  
  724. ;-------------------------------------------------
  725.  
  726. VD_TUCData    moveq    #0,d1
  727.         move.w    $1c(a0),d1
  728.         add.w    #$1e,d1            ;start of packed data
  729.         sub.l    d1,d0
  730.         cmp.l    #4,d0            ;at least one longword
  731.         blt.s    .Exit
  732.  
  733.         movem.l    d2-d7/a2/a6,-(a7)
  734.         move.l    d0,d6            ;bytes still there
  735.         move.l    8(a0),d3        ;calculate EOR value
  736.         eor.l    #"M.F.",d3
  737.         neg.l    d3
  738.         swap    d3
  739.         ror.l    #8,d3
  740.         bsr.s    TUCData_GetLen
  741.         move.l    a2,d0
  742.         sub.l    a0,d0
  743.         movem.l    (a7)+,d2-d7/a2/a6
  744.         tst.w    d1
  745.         beq.s    .Exit
  746.         rts
  747.  
  748. .Exit        moveq    #0,d0
  749.         rts
  750.  
  751. TUCData_GetLen    moveq    #0,d7
  752.         move.b    2(a0),d7        ;bit width of data
  753.         lea    $1c(a0),a2        ;data table
  754.  
  755.         moveq    #0,d5
  756.         move.w    (a2)+,d0        ;info table length
  757.         move.l    a2,a6            ;info table
  758.         lea    (a2,d0.w),a2
  759.         move.w    d7,d1            ;bit width of hunk length
  760.         bsr.s    .GetBitsD6
  761.         move.l    d0,d4            ;hunk length
  762.  
  763. .lbC000062    moveq    #0,d0
  764. .lbC000064    asl.l    #1,d5            ;get value from info table
  765.         bne.s    .lbC000072
  766.         move.l    (a2)+,d5
  767.         subq.l    #4,d6
  768.         bmi.s    .Error
  769.         eor.l    d3,d5
  770.         move.b    #$10,ccr
  771.         roxl.l    #1,d5
  772. .lbC000072    bcc.s    .lbC000076
  773.         addq.w    #2,d0
  774. .lbC000076    move.w    (a6,d0.w),d0        ;loop until negative
  775.         bpl.s    .lbC000064
  776.         not.w    d0
  777.  
  778.         cmp.w    #$100,d0        ;less than $100 -> data byte
  779.         bcs.s    .lbC0000F0
  780.         bne.s    .lbC0000A6        ;more than $100 -> crunched
  781.  
  782. * reloc info
  783.  
  784. .Error        moveq    #0,d1            ;error
  785.         rts
  786.  
  787. * crunched
  788.  
  789. .lbC0000A6    cmp.w    #$110,d0        ;$101-$110
  790.         bhi.s    .lbC0000C6
  791.         sub.w    #$101,d0
  792.         move.w    d0,d1            ;value 0-$f
  793.         bsr.s    .GetBitsD6
  794.         sub.l    d0,d4
  795.         moveq    #7,d1
  796.         bsr.s    .GetBitsD6
  797.         subq.l    #2,d4
  798.         bra.s    .lbC0000F2
  799.  
  800. .lbC0000C6    move.w    d0,d2            ;$111-$1ff
  801.         move.w    d0,d1
  802.         and.w    #15,d1
  803.         bsr.s    .GetBitsD6
  804.         addq.w    #3,d0            ;length of string
  805.         sub.l    d0,d4
  806.         move.w    d2,d1
  807.         lsr.w    #4,d1
  808.         and.w    #15,d1
  809.         addq.w    #2,d1
  810.         bsr.s    .GetBitsD6
  811.  
  812. * copy uncrunched byte
  813.  
  814. .lbC0000F0    subq.l    #1,d4
  815. .lbC0000F2    bgt.s    .lbC000062
  816.         bmi.s    .Error
  817.         moveq    #1,d1
  818.         rts
  819.  
  820. .GetBitsD6    moveq    #0,d0
  821. .lbC00013A    asl.l    #1,d5
  822.         bne.s    .lbC000148
  823.         move.l    (a2)+,d5
  824.         subq.l    #4,d6
  825.         bge.s    .Ok
  826.         addq.w    #4,a7
  827.         bra.s    .Error
  828. .Ok        eor.l    d3,d5
  829.         move.b    #$10,ccr
  830.         roxl.l    #1,d5
  831. .lbC000148    roxl.l    #1,d0
  832.         dbra    d1,.lbC00013A
  833.         rts
  834.  
  835. ;-------------------------------------------------
  836.  
  837. DB_TUCData    movem.l    d2-d7/a2-a6,-(a7)
  838.         move.l    a0,a5
  839.         move.l    xfdbi_MinTargetLen(a5),d0
  840.         move.l    d0,xfdbi_TargetBufSaveLen(a5)
  841.         move.l    d0,xfdbi_TargetBufLen(a5)
  842.  
  843.         move.w    xfdbi_Flags(a5),d1
  844.         and.w    #XFDFF_USERTARGET,d1
  845.         beq.s    .Alloc
  846.         move.l    xfdbi_UserTargetBuf(a5),d0
  847.         bra.s    .UserTarget
  848. .Alloc        move.l    xfdbi_TargetBufMemType(a5),d1
  849.         move.l    4.w,a6
  850.         jsr    -198(a6)
  851. .UserTarget    move.w    #XFDERR_NOMEMORY,xfdbi_Error(a5)
  852.         move.l    d0,xfdbi_TargetBuffer(a5)
  853.         beq.s    .Exit
  854.         
  855.         move.l    d0,a1
  856.         move.l    xfdbi_SourceBuffer(a5),a0
  857.         move.l    8(a0),d3        ;calculate EOR value
  858.         eor.l    #"M.F.",d3
  859.         neg.l    d3
  860.         swap    d3
  861.         ror.l    #8,d3
  862.  
  863.         bsr.s    TUCData_Decr
  864.         tst.w    d0
  865.         bne.s    .Exit
  866.  
  867. .Free        move.w    xfdbi_Flags(a5),d1
  868.         and.w    #XFDFF_USERTARGET,d1
  869.         bne.s    .UserTarget2
  870.         move.l    xfdbi_TargetBuffer(a5),a1
  871.         move.l    xfdbi_TargetBufLen(a5),d0
  872.         move.l    4.w,a6
  873.         jsr    -210(a6)
  874. .UserTarget2    move.w    #XFDERR_CORRUPTEDDATA,xfdbi_Error(a5)
  875.         moveq    #0,d0
  876. .Exit        movem.l    (a7)+,d2-d7/a2-a6
  877.         rts
  878.  
  879. TUCData_Decr    moveq    #0,d7
  880.         move.b    2(a0),d7        ;bit width of data
  881.         lea    $1c(a0),a2        ;data table
  882.  
  883.         moveq    #0,d5
  884.         move.w    (a2)+,d0        ;info table length
  885.         move.l    a2,a6            ;info table
  886.         lea    (a2,d0.w),a2
  887.         move.w    d7,d1            ;bit width of hunk length
  888.         bsr    TUC_GetBits
  889.         move.l    d0,d4            ;hunk length
  890.         add.l    a1,d4            ;end of hunk
  891.  
  892. .lbC000062    moveq    #0,d0
  893. .lbC000064    asl.l    #1,d5            ;get value from info table
  894.         bne.s    .lbC000072
  895.         move.l    (a2)+,d5
  896.         eor.l    d3,d5
  897.         move.b    #$10,ccr
  898.         roxl.l    #1,d5
  899. .lbC000072    bcc.s    .lbC000076
  900.         addq.w    #2,d0
  901. .lbC000076    move.w    (a6,d0.w),d0        ;loop until negative
  902.         bpl.s    .lbC000064
  903.         not.w    d0
  904.  
  905.         cmp.w    #$100,d0        ;less than $100 -> data byte
  906.         bcs.s    .lbC0000F0
  907.         bne.s    .lbC0000A6        ;more than $100 -> crunched
  908.  
  909. * reloc info
  910.  
  911. .Error        moveq    #0,d0            ;error
  912.         rts
  913.  
  914. * crunched
  915.  
  916. .lbC0000A6    cmp.w    #$110,d0        ;$101-$110
  917.         bhi.s    .lbC0000C6
  918.         sub.w    #$101,d0
  919.         move.w    d0,d1            ;value 0-$f
  920.         bsr    TUC_GetBits
  921.         move.w    d0,d2            ;amount of same bytes
  922.         moveq    #7,d1
  923.         bsr    TUC_GetBits
  924. .lbC0000BE    move.b    d0,(a1)+        ;copy same bytes
  925.         cmp.l    d4,a1
  926.         beq.s    .Error
  927.         dbra    d2,.lbC0000BE
  928.         bra.s    .lbC0000F0
  929.  
  930. .lbC0000C6    move.w    d0,d2            ;$111-$1ff
  931.         move.w    d0,d1
  932.         and.w    #15,d1
  933.         bsr    TUC_GetBits
  934.         addq.w    #3,d0            ;length of string
  935.         move.w    d2,d1
  936.         move.w    d0,d2
  937.         lsr.w    #4,d1
  938.         and.w    #15,d1
  939.         addq.w    #2,d1
  940.         bsr    TUC_GetBits
  941.         neg.l    d0            ;offset
  942. .lbC0000E6    move.b    (a1,d0.l),(a1)+
  943.         cmp.l    d4,a1
  944.         dbeq    d2,.lbC0000E6
  945.         tst.w    d2
  946.         ble.s    .lbC0000F2
  947.         bra.s    .Error
  948.  
  949. * copy uncrunched byte
  950.  
  951. .lbC0000F0    move.b    d0,(a1)+
  952. .lbC0000F2    cmp.l    d4,a1            ;end of hunk ??
  953.         bne    .lbC000062
  954.         moveq    #1,d0
  955.         rts
  956.  
  957.  
  958.         END